package com.bl.student.service.biz.main.impl;

import com.bl.student.common.ApiResponseCode;
import com.bl.student.common.CommonServiceException;
import com.bl.student.common.enums.PointType;
import com.bl.student.common.enums.UserStatus;
import com.bl.student.common.utils.ASE;
import com.bl.student.common.utils.Generator;
import com.bl.student.common.utils.ListUtils;
import com.bl.student.common.utils.UUIDUtils;
import com.bl.student.dao.model.PointEntity;
import com.bl.student.dao.model.TeacherEntity;
import com.bl.student.dao.model.UserEntity;
import com.bl.student.dao.redis.MessageDao;
import com.bl.student.dao.redis.UserInfoDao;
import com.bl.student.dao.redis.model.UserInfo;
import com.bl.student.dao.repository.PointRepository;
import com.bl.student.dao.repository.TeacherRepository;
import com.bl.student.dao.repository.UserRepository;
import com.bl.student.dao.repository.UserTagRepository;
import com.bl.student.service.biz.main.MainService;
import com.bl.student.service.biz.user.UserService;
import com.bl.student.service.vo.main.*;
import com.bl.student.service.vo.user.UserInfoModifyVo;
import com.bl.student.tp.hx.user.*;
import com.bl.student.tp.wechat.auth.WechatAccessTokenMiniRequest;
import com.bl.student.tp.wechat.auth.WechatAccessTokenResponse;
import com.bl.student.tp.wechat.auth.WechatAuthApi;
import com.gexin.fastjson.JSONObject;
import com.google.common.base.Optional;
import com.google.common.base.Strings;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * Created by yujingyi on 2018/1/18.
 */
@Log4j2
@Service
public class MainServiceImpl implements MainService {

    private final String REGISTER_DUPLICATED_PHONE = "该手机号码已被注册";
    private final String REGISTER_DUPLICATED_ACCOUNT = "该帐号已被注册";

    @Autowired
    MessageDao messageDao;

    @Autowired
    UserService userService;

    @Autowired
    UserRepository userRepository;

    @Autowired
    HxUserApi hxUserApi;

    @Autowired
    UserInfoDao userInfoDao;

    private boolean verifyCaptcha(String mobile, String captcha) {
        String code = messageDao.getAuthCode(mobile);
        if (code == null || !code.equals(captcha)) {
            return false;
        }
        return true;
    }

    @Override
    @Transactional
    public RegisterResponseVo register(RegisterVo registerVo) {

        if (userService.getUserByMobile(registerVo.getMobile()) != null) {
            throw new CommonServiceException(ApiResponseCode.DATA_EXISTED.getCode(), REGISTER_DUPLICATED_PHONE);
        }

        if (registerVo.getMobile().contains("+")) {
            registerVo.setMobile(registerVo.getMobile().replace("+", "%2b"));
        }

        if (!verifyCaptcha(registerVo.getMobile(), registerVo.getCaptcha()) && !"111111".equals(registerVo.getCaptcha())) {
            throw new CommonServiceException(ApiResponseCode.CAPTCHA_WRONG.getCode(), ApiResponseCode.CAPTCHA_WRONG.getMsg());
        }

        if (userService.getUserByNickname(registerVo.getNickname()) != null) {
            return null;
        }


        UserEntity userEntity = new UserEntity();
        int userId = UUIDUtils.getUUID();
        if (registerVo.getMobile().contains("%2b")) {
            registerVo.setMobile(registerVo.getMobile().replace("%2b", "+"));
        }
        userEntity.setId(userId);
        userEntity.setMobile(registerVo.getMobile());
        userEntity.setPassword(registerVo.getPassword());
        userEntity.setNickname(registerVo.getNickname());
        userEntity.setCreateTime(new Date());
        userEntity.setUpdateTime(new Date());
        userRepository.save(userEntity);

        RegisterResponseVo registerResponseVo = RegisterResponseVo.builder()
                .id(userId)
                .nickName(userEntity.getNickname())
                .build();

        return registerResponseVo;
    }

    @Override
    public LoginResponseVo appLogin(LoginVo loginVo) {
        UserEntity userEntity = fetchAvailableUser(loginVo.getMobile(), loginVo.getPassword());

        String token = Generator.generateToken(userEntity.getId(), userEntity.getMobile(), userEntity.getPassword(), loginVo.getSid());

        UserInfo userInfo = new UserInfo();
        userInfo.setId(userEntity.getId());
        userInfo.setMobile(userEntity.getMobile());
        userInfo.setAccount(userEntity.getAccount());
        userInfo.setToken(token);
        userInfo.setLoginTime(System.currentTimeMillis() + "");
        userInfo.setSId(loginVo.getSid());
        userInfo.setCId(loginVo.getCid());

        userInfoDao.setUserInfo(userInfo);

        LoginResponseVo loginResponseVo = LoginResponseVo.builder()
                .mobile(userEntity.getMobile())
                .token(token)
                .nickName(userEntity.getNickname())
                .id(userEntity.getId())
                .sId(loginVo.getSid())
                .build();

        return loginResponseVo;
    }

    @Override
    public LoginResponseVo appLoginByName(LoginVo loginVo) {
        UserEntity userEntity = fetchAvailableUserByName(loginVo.getMobile(), loginVo.getPassword());

        String token = Generator.generateToken(userEntity.getId(), userEntity.getMobile(), userEntity.getPassword(), loginVo.getSid());

        UserInfo userInfo = new UserInfo();
        userInfo.setId(userEntity.getId());
        userInfo.setMobile(userEntity.getMobile());
        userInfo.setAccount(userEntity.getAccount());
        userInfo.setToken(token);
        userInfo.setLoginTime(System.currentTimeMillis() + "");
        userInfo.setSId(loginVo.getSid());
        userInfo.setCId(loginVo.getCid());

        userInfoDao.setUserInfo(userInfo);

        LoginResponseVo loginResponseVo = LoginResponseVo.builder()
                .mobile(userEntity.getMobile())
                .token(token)
                .nickName(userEntity.getNickname())
                .id(userEntity.getId())
                .sId(loginVo.getSid())
                .build();

        return loginResponseVo;
    }

    private UserEntity fetchAvailableUser(String mobile, String password) {
        UserEntity userEntity = userService.getUserByMobile(mobile);

        if (userEntity == null) {
            throw new CommonServiceException(ApiResponseCode.USER_NOT_EXIST.getCode(), ApiResponseCode.USER_NOT_EXIST.getMsg());
        }

        if (!userEntity.getPassword().equals(password)) {
            throw new CommonServiceException(ApiResponseCode.PASSWORD_WRONG.getCode(), ApiResponseCode.PASSWORD_WRONG.getMsg());
        }

        return userEntity;
    }

    private UserEntity fetchAvailableUserByName(String userName, String password) {
        UserEntity userEntity = userService.getUserByNickname(userName);

        if (userEntity == null) {
            throw new CommonServiceException(ApiResponseCode.USER_NOT_EXIST.getCode(), ApiResponseCode.USER_NOT_EXIST.getMsg());
        }

        if (!userEntity.getPassword().equals(password)) {
            throw new CommonServiceException(ApiResponseCode.PASSWORD_WRONG.getCode(), ApiResponseCode.PASSWORD_WRONG.getMsg());
        }

        return userEntity;
    }

    private void handleInvitedCode() {

    }

    @Override
    public void reset(ResetVo resetVo) {
        UserEntity userEntity = userService.getUserByMobile(resetVo.getMobile());
        if (userEntity == null) {
            throw new CommonServiceException(ApiResponseCode.USER_NOT_EXIST.getCode(), ApiResponseCode.USER_NOT_EXIST.getMsg());
        }
        if (!verifyCaptcha(resetVo.getMobile(), resetVo.getCaptcha())) {
            throw new CommonServiceException(ApiResponseCode.CAPTCHA_WRONG.getCode(), ApiResponseCode.CAPTCHA_WRONG.getMsg());
        }
        userEntity.setPassword(resetVo.getPassword());


        userRepository.save(userEntity);

    }

    @Override
    public void logout(UserInfo userInfo) {
        userInfoDao.delUserInfo(userInfo.getMobile());
    }

    @Override
    @Transactional
    public void modifyUser(UserInfoModifyVo userInfoModifyVo) {
        UserEntity userEntity = userRepository.findOne(userInfoModifyVo.getId());
        if (userEntity == null) {
            throw new CommonServiceException(ApiResponseCode.DATA_NOT_EXIST);
        }

        userEntity.setNickname(userInfoModifyVo.getNickname());

        userRepository.save(userEntity);
    }

}
